#ifndef _PROTOCOL_API_H_
#define _PROTOCOL_API_H_

#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

/* 协议固定参数定义 */
// 协议同步码
#define PROTOCOL_SYNCWORD_CODE                      0xA1

/* 定义各字段数据长度 */
// 同步码字段长度
#define PROTOCOL_SYNCWORD_BIT_LENGTH                (1ul)
// 数据长度字段长度
#define PROTOCOL_DATA_SIZE_BIT_LENGTH               (2ul)
// 控制命令字段长度
#define PROTOCOL_CMD_BIT_LENGTH                     (1ul)
// 版本号字段长度
#define PROTOCOL_VERSION_BIT_LENGTH                 (1ul)
// 验证码字段长度
#define PROTOCOL_CAPTCHA_BIT_LENGTH                 (4ul)
// MAC编码字段长度
#define PROTOCOL_INDEX_BIT_LENGTH                   (8ul)
// 时间戳字段长度
#define PROTOCOL_TIMESTAMP_BIT_LENGTH               (4ul)
// 随机数字段长度
#define PROTOCOL_RANDOM_BIT_LENGTH                  (4ul)
// 附带数据数据长度
#define PROTOCOL_ATTACHED_DATA_LENGTH               (522ul)
// 校验码字段长度
#define PROTOCOL_CHECK_CODE_BIT_LENGTH              (1ul)
// 固定字段长度
#define PROTOCOL_FIXED_BIT_LENGTH                   (25ul)

/* 定义各种数据长度 */
// 持卡人描述文件长度
#define MAX_CARDHOLDER_DESCRIBES_FILE_LENGTH        (512ul)
// 单次请求图像数据长度
#define SINGLE_REQUEST_FILE_LENGTH                  (512ul)
// 单次获取日志文件长度
#define OBTAIN_THE_LOG_FILE_LENGTH_EACH_TIME        (512ul)
// 单次获取日志最大条数
#define MAX_NUMBER_OF_LOG_TABLE_GET                 (28ul)
// 单次通讯测试数据传输长度
#define SINGLE_COMMUNICATION_TEST_DATA_LENGTH       (512ul)

// 设备索引掩码
#define PROTOCOL_DEVICE_INDEX_MASK                  (0x5947)

// 查询标志
#define PROTOCOL_ENQUIRY_FLAG                       PROTOCOL_DUMMY_CODING
// 日志携带数据长度
#define LOG_ATTACHED_DATA_LENGTH                    USER_AUTHENTICATION_KEY_LENGTH
// 消息包长度
#define PROTOCOL_LENGTH_OF_SINGLE_MESSAGE_PACKET    NOMINAL_PACKET_LENGTH

// 低压保护阈值
//#define PROTOCOL_LOW_VOLTAGE_PROTECTION_THRESHOLD   LOW_BATTERY_ALERT_THRESHOLD

/**
 * @brief 定义设备参数子命令编码
 *
 */
typedef enum
{
  SUBCOMMAND_DEVICE_TYPE                   = 0x10, // 设备类型
  SUBCOMMAND_DATA_OF_PRODUCTION            = 0x11, // 出厂日期
  SUBCOMMAND_BOARD_VERSION                 = 0x12, // 电路板版本
  SUBCOMMAND_FIRMWARE_VERSION              = 0x13, // 固件版本
  SUBCOMMAND_QUALITY_INSPECTOR             = 0x14, // 质检员编码
  SUBCOMMAND_NUMBER_OF_REGISTERED_FACE     = 0x15, // 注册人脸数量
  SUBCOMMAND_CAMERA_MODULE_SERIAL_NUMBER   = 0x16, // 摄像头模组序列号
  SUBCOMMAND_CAMERA_MODULE_VERSION         = 0x17, // 摄像头模组固件版本
  SUBCOMMAND_NUMBER_OF_REGISTERED_FINGER   = 0x18, // 注册指纹数量
  SUBCOMMAND_FINGER_MODULE_SERIAL_NUMBER   = 0x19, // 指纹模组序列号
  SUBCOMMAND_FINGER_MODULE_VERSION         = 0x1A, // 指纹模组固件版本
  SUBCOMMAND_WIRELESS_MODULE_SERIAL_NUMBER = 0x1B, // 无线模组序列号
  SUBCOMMAND_WIRELESS_MODULE_VERSION       = 0x1C, // 无线模组固件版本
  SUBCOMMAND_SIM_ICCID                     = 0x1D, // SIM 卡唯一编码
  SUBCOMMAND_CHIP_MODEL_NUMBER             = 0x1E, // 芯片型号
  SUBCOMMAND_IMSI_CODE                     = 0x1F, // IMSI 编码
  SUBCOMMAND_FACE_ALGORITHM_VERSION        = 0x20, // 算法版本
} DeviceParameterSubCmd_t;

/**
 * @brief 设备自检结果
 *
 */
typedef enum
{
  SELF_CHECK_IDLE                          = 0x00, // 空闲
  SELF_CHECK_BUSY                          = 0x01, // 繁忙
  SELF_CHECK_DONE                          = 0x02, // 完成
} SelfTestCheckResult_t;

/**
 * @brief 设备自检状态
 *
 */
typedef enum
{
  SELF_TEST_RESULT_SUCCESS                 = 0x00, // 成功
  SELF_TEST_RESULT_ERROR                   = 0x01, // 失败
  SELF_TEST_RESULT_NO_SUPPORT              = 0x02, // 不存在
} DevSelfTestResult_t;

/**
 * @brief 无线模组网络附着状态操作
 *
 */
typedef enum
{
  START_WIRELESS_MODULE_NET_ATTA           = 0x00, // 启动网络附着
  QUERY_NET_ATTA_STATUS                    = 0x01, // 查询网络附着状态
} WirelessNetAttaOperation_t;

/**
 * @brief 本地注册状态
 *
 */
typedef enum
{
  LOCAL_REGISTER_STATUS_IDLE                = 0x00, // 空闲
  LOCAL_REGISTER_STATUS_BUSY                = 0x01, // 正在进行
  LOCAL_REGISTER_STATUS_DONE                = 0x02, // 完成
  LOCAL_REGISTER_STATUS_ERROR               = 0x03, // 失败
  LOCAL_REGISTER_STATUS_USER_EXIT           = 0x04, // 用户退出
  LOCAL_REGISTER_STATUS_DEVICE_BUSY         = 0x05, // 设备繁忙
  LOCAL_REGISTER_STATUS_SINGLE_USER_LIMIT   = 0x06, // 超过用户上限
  LOCAL_REGISTER_STATUS_KEY_ALREADY_EXISTS  = 0x07, // 密钥已存在
  LOCAL_REGISTER_STATUS_DEVICE_NOT_SUPPORT  = 0x08, // 设备不支持
  LOCAL_REGISTER_STATUS_CARDHOLDER_IS_FULL  = 0x09, // 持卡人已满
  LOCAL_REGISTER_STATUS_SAFETY_USER_IS_FULL = 0x0A, // 外部模组用户已满
  LOCAL_REGISTER_STATUS_WAIT_SAVE           = 0x0B, // 录入成功，待保存
} LocalRegisterStatus_t;

/**
 * @brief 本地注册步骤
 *
 */
typedef enum
{
  LOCAL_REGISTER_WAIT_TIGGER                = 0x00, // 等待触发
  LOCAL_REGISTER_PLACE_THE_CARD             = 0x01, // 请按下卡片
  LOCAL_REGISTER_ENTER_PASSWORD             = 0x02, // 请输入密码
  LOCAL_REGISTER_REPEAT_PASSWORD            = 0x03, // 请再次输入密码
  LOCAL_REGISTER_START_FACE_REGISTER        = 0x04, // 开始注册人脸
  LOCAL_REGISTER_FACE_CAMERA_DIRECTLY       = 0x05, // 请直接对准摄像头
  LOCAL_REGISTER_LOOK_UP                    = 0x06, // 请向上抬头
  LOCAL_REGISTER_LOOK_DOWN                  = 0x07, // 请向下低头
  LOCAL_REGISTER_LOOK_LEFT                  = 0x08, // 请向左转头
  LOCAL_REGISTER_LOOK_RIGHT                 = 0x09, // 请向右转头
  LOCAL_REGISTER_PRESS_FINGER               = 0x0A, // 请按手指
  LOCAL_REGISTER_REPEAT_FINGER_1            = 0x0B, // 请再次按手指(1)
  LOCAL_REGISTER_REPEAT_FINGER_2            = 0x0C, // 请再次按手指(2)
} LocalRegisterStep_t;

/**
 * @brief 卡顶替动作类型
 *
 */
typedef enum
{
  CARD_REPLACE_SET                          = 0x10, // 设置
  CARD_REPLACE_GET                          = 0x11, // 查询
} CardReplaceAction_t;

typedef enum
{
  LOCK_CLASSIFICATION_SET                   = 0x10, // 设置
  LOCK_CLASSIFICATION_GET                   = 0x11, // 查询
} LockClassificationAction_t;

/**
 * @brief 开锁方式
 *
 */
typedef enum
{
  DOOR_LOCK                                 = 0x10, // 关锁
  DOOR_UNLOCK                               = 0x11, // 开锁
  DOOR_NORMAL_OPEN                          = 0x12, // 常开模式
} UnlockingMethod_t;

/**
 * @brief 网络子命令编码
 *
 */
typedef enum
{
  SUBCOMMAND_DNS_CODEING                       = 0x10, // DNS编码
  SUBCOMMAND_SUBNET_MASK_CODEING               = 0x11, // 子网掩码
  SUBCOMMAND_LOCAL_IP_CODEING                  = 0x12, // 本地IP编码
  SUBCOMMAND_GATEWAY_IP_CODEING                = 0x13, // 网关IP编码
  SUBCOMMAND_DOMAIN_NAME_CODEING               = 0x14, // 服务器IP编码
  SUBCOMMAND_SERVER_PORT_CODEING               = 0x15, // 服务器端口号
  SUBCOMMAND_HOST_NAME_CODEING                 = 0x16, // 主机名称
  SUBCOMMAND_MQTT_USER_NAME_CODEING            = 0x17, // 用户名
  SUBCOMMAND_MQTT_PASSWORD_CODEING             = 0x18, // 登录密码
  SUBCOMMAND_MQTT_SUBSCRIBE_TOPICS_CODEING     = 0x19, // 订阅主题编码
  SUBCOMMAND_MQTT_PUBLISH_TOPICS_CODEING       = 0x1A, // 推送主题编码
  SUBCOMMAND_TARGET_SERVER_CONNECT_IP_ADDRESS  = 0x1B, // 目标服务器连接IP地址
  SUBCOMMAND_TARGET_WIFI_SSID                  = 0x1C, // 目标wifi连接SSID
  SUBCOMMAND_TARGET_WIFI_PW                    = 0x1D, // 目标wifi连接PW
  SUBCOMMAND_LOOK_MAC                          = 0x1E, // 门锁mac
} NetworkSubCmd_t;

/**
 * @brief 文件类型
 *
 */
typedef enum
{
  FILE_FACE_PICTURE                        = 0x10, // 人脸图片
  FILE_FACE_EIGENVALUE                     = 0x11, // 人脸特征值
  FILE_FINGER_EIGENVALUE                   = 0x12, // 指纹特征值
  FILE_UPDATE_FIEMWARE_PACKET              = 0x13, // 更新固件
} DocumentType_t;

/**
 * @brief 报文解析应答码
 *
 */
typedef enum
{
  MESSAGE_PRASE_SUCCESS                    = 0xE0, // 解析成功
  MESSAGE_CMD_UNKNOW                       = 0xE1, // 未知命令
  MESSAGE_ERROR_DELIVER_PARAM              = 0xE2, // 下发参数错误
  WRITE_MEMORY_ERROR                       = 0xE3, // 写内存失败
  TARGET_DEVICE_BUSY                       = 0xE4, // 目标设备繁忙
  COMMAND_NOT_SUPPORTED                    = 0xE5, // 命令不支持
  DEVICE_IS_LOCKED                         = 0xE6, // 设备处于锁定状态
  CARDHOLDER_ALREADY_EXISTS                = 0xE7, // 持卡人已存在
  EXCEED_USER_LIMIT                        = 0xE8, // 超过用户上限
  USER_DOES_NOT_EXIST                      = 0xE9, // 用户不存在
  OPERATION_FAILURE                        = 0xEA, // 操作失败
  VERSION_INCONSISTENCY                    = 0xEB, // 协议版本不一致
  DEVICE_NOT_AUTHORISED                    = 0xEC, // 设备未授权
  CMD_LIFE_CYCLE_FAILURE                   = 0xED, // 命令声明周期失效
  OVER_OF_SINGLE_USER_REGISTER             = 0xEE, // 超过单用户注册上限
  PERMISSION_DENIED                        = 0xEF, // 权限不足
  LOW_BATTERY_ALARM                        = 0xF0, // 低电量报警
  FAILED_TO_ENTER_OTA_MODE                 = 0xF1, // 进入OTA模式失败
  OPERATION_TIMED_OUT_PLEASE_RETRY         = 0xF3, // 操作超时 请重试
  SAFETY_USER_IS_FULL                      = 0xF4, // 外部模组用户已满
} ProtocolPraseResult_t;

/**
 * @brief 命令码表
 *
 */
typedef enum
{
  // 工厂维护仅生产环境下有效
  PLANT_DEVICE_FUNCTION                    = 0x00, // 设置设备功能
  PLANT_PRODUCT_MODEL                      = 0x01, // 产品型号
  PLANT_SET_NUMBER_OF_CARDHOLDER           = 0x03, // 设置持卡人数量
  PLANT_GET_DEVICE_MODULE_STATUS           = 0x04, // 获取设备板载模组状态
  PLANT_START_DEVICE_SELF_TEST             = 0x05, // 启动设备自检

  // 系统维护
  SYSTEM_HEARTBEAT_CMD                     = 0x10, // 心跳
  SYSTEM_DEVICE_REBOOT                     = 0x11, // 重启
  SYSTEM_FACTORY_RESET                     = 0x12, // 恢复出厂设置
  SYSTEM_DEVICE_PARAM                      = 0x13, // 设备参数
  SYSTRM_DAYS_REMAINING                    = 0x14, // 播报天数
  SYSTEM_READR_CARD_MODE                   = 0x15, // 卡片识读类型
  SYSTEM_HARDWARE_PROPERTIES               = 0x16, // 获取设备属性
  SYSTEM_SET_REAL_TIME                     = 0x17, // 设置实时时间
  SYSTEM_OWNERSHIP                         = 0x18, // 设置门锁归属
  WIRELESS_MODULE_NET_ATTA                 = 0x19, // 无线模组网络附着
  SYSTEM_DEVICE_HANDSHAKE                  = 0x1A, // 设备握手
  SYSTEM_CARD_REPLACE_TIME                 = 0x1B, // 清除、获取特定卡类型顶替时间
  SYSTEM_NO_DISTURBING_CONFIG              = 0x1C, // 免打扰配置
  SYSTEM_LOCK_CLASSIFICATION               = 0x1D, // 门锁分类/分组

  // 持卡人管理
  CARDHOLDER_NUMBER_OF_REGISTERED          = 0x20, // 获取注册用户数量
  CARDHOLDER_GET_INFORMATION               = 0x21, // 查询单个持卡人信息
  CARDHOLDER_NEW_CARDHOLDER                = 0x22, // 新建持卡人
  CARDHOLDER_DELETE_CARDHOLDER             = 0x23, // 删除持卡人
  CARDHOLDER_MODIFY_PERMISSIONS            = 0x24, // 修改持卡人权限
  CARDHOLDER_LOCAL_ENTRY                   = 0x25, // 本地录入用户
  CARDHOLDER_REGISTERED_INFORMATION        = 0x26, // 持卡人注册信息上报
  CARDHOLDER_GET_CARDHOLDER_LIST           = 0x27, // 获取持卡人文件信息
  CARDHOLDER_GET_FILE_PACKET               = 0x28, // 获取持卡人文件
  CARDHOLDER_BATCH_ADDITIONS               = 0x29, // 批量新增持卡人
  CARDHOLDER_BATCH_DETETION                = 0x2A, // 批量删除持卡人
  CARDHOLDER_GET_LOCAL_REGISTER_STATUS     = 0x2B, // 获取本地注册状态

  // 文件管理
  REPORT_FILE_ATTRIBUTE                    = 0x30, // 报告图像属性
  UPLOAD_FILE_DATA_PACKET                  = 0x31, // 上传图像

  // 开锁动作
  COMMAND_REMOTE_DOOR_OPENING              = 0x41, // 远程开门
  QROCDE_SCANF_DOOR_OPENING                = 0x42, // 二维码开门
  QROCDE_SCANF_PATROL                      = 0x43, // 二维码巡更
  BLUETOOTH_VIRTUAL_CARD                   = 0x45, // 蓝牙虚拟卡

  // 网络维护
  NETWORK_INFORM_ATTRIBUTE                 = 0x50, // 网络属性

  // 文件上下发
  FILE_NOTIFIES_ATTRIBUTR                  = 0x60, // 获取图像编码
  FILE_SEND_DATA_PCAKET                    = 0x61, // 请求图像文件
  FILE_REQUEST_EIGENVALUE_ATTRIBUTR        = 0x62, // 请求特征值文件属性
  FILE_REQUEST_EIGENVALUE_FILE             = 0x63, // 请求特征值文件

  // 日志管理
  LOG_REAL_TIME_EVENT_REPORTING            = 0xA0, // 实时上报事件
  LOG_NUMBER_OF_LOGS_OBTAINED              = 0xA1, // 获取日志条数
  LOG_OBTAIN_NUMBER_OF_CACHE               = 0xA2, // 获取缓存日志

  //第三方服务
  OTHER_TRANSFER_DATA                      = 0xFA, // 下发中转数据
  OTHER_UPLOAD_MESSAGE                     = 0xFB, // 主动上传报文
  OTHER_EXTERL_HOST_VALIDATION             = 0xFC, // 外部主机验证
  OTHER_CONNECT_TEST                       = 0xFF, // 测试命令
} ProtocolCommandWord_t;

/**
 * @brief 模组状态字段内容
 *
 */
typedef union
{
  uint16_t Status; // 模组综合状态

  struct ModuleBitStatusClass
  {
    uint16_t Rfid           : 2; // 读卡
    uint16_t Keyboard       : 2; // 键盘
    uint16_t Camera         : 2; // 摄像头
    uint16_t Finger         : 2; // 指纹
    uint16_t WirelessModule : 2; // 无线模组
    uint16_t Reserved       : 6; // 预留
  } ModuleBitStatus;
} ModuletatusFormat_t;

/**
 * @brief 描述时间区域格式
 *
 */
typedef struct
{
  uint8_t StartHour;   // 开始时
  uint8_t StartMinute; // 开始分
  uint8_t EndHour;     // 结束时
  uint8_t EndMinute;   // 结束分
} TimePeriod_t;

/**
 * @brief 设备功能字段内容
 *
 */
typedef struct
{
  uint8_t Function; // 设备功能
} DeviceFunctionFormat_t;

/**
 * @brief 描述产品信息字段内容
 *
 */
typedef struct
{
  uint8_t DeviceType;                                        // 设备类型
  uint32_t DateOfProduction;                                 // 出厂日期
  uint8_t QualityControlCode[NUMBER_OF_QC_CODE];             // 质检员编码
  uint8_t ChipModel[NUMBER_OF_CHIP_TYPE_LENGTH];             // 芯片型号
  uint8_t BoardVersionNumber[NUMBER_OF_FIRMWARE_VERSION];    // 电路板版本
  uint8_t FirmwareVersionNumber[NUMBER_OF_FIRMWARE_VERSION]; // 固件版本
} ProductformationFormat_t;

/**
 * @brief 设置持卡人上限字段内容
 *
 */
typedef struct
{
  uint8_t NumberOfCardholders; // 持卡人上限
} SetNumberOfCardholderFormat_t;

/**
 * @brief 获取模组状态字段内容
 *
 */
typedef struct
{
  uint8_t BatteryLevel;            // 剩余电量百分比
  uint8_t SelfTestResult;          // 自检结果
  ModuletatusFormat_t Moduletatus; // 模组状态
} GetSelfTestStatusFormat_t;

/**
 * @brief 定义心跳协议字段内容
 *
 */
typedef struct
{
  uint8_t TimeZone;      // 时区
  uint32_t RealTimeTime; // 实时时间
} HeartbeatFormat_t;

/**
 * @brief 设备参数字段内容
 *
 */
typedef struct
{
  uint8_t Sensitivity;                  // 键盘灵敏度
  uint8_t SystemVolume;                 // 系统音量
  uint8_t UnlockingTime;                // 开锁时间
  uint8_t MotorDriveTime;               // 电机驱动时间
  uint8_t ErrorsExcepted;               // 时间补偿
  uint8_t NetworkOperator;              // 网络运营商
  uint8_t CameraReadModel;              // 识读模式
  uint16_t HeartbeatInterval;           // 心跳间隔
  uint8_t CameraSearchTimeout;          // 人脸检索时间
  uint8_t BluetoothConnectTime;         // 蓝牙连接时间
  uint8_t OfflineCardFunctionEn;        // 离线卡功能使能
  uint8_t LockedInReminderInterval;     // 反锁间隔提示时间
  uint8_t BreakInDetectionInterval;     // 撬锁间隔检测时间
  uint8_t FlaseLockDetectionInterval;   // 假锁间隔检测时间
  uint8_t NormalOpenReminderInterval;   // 常开间隔提示时间
  uint8_t BluetoothUpdateRadioInterval; // 蓝牙更新广播间隔
  uint8_t Reserved[10];                 // 预留
} ParameterOfApparatusFormat_t;

/**
 * @brief 到期播报字段内容
 *
 */
typedef struct
{
  uint8_t En;   // 使能位
  uint8_t Days; // 开始播放天数
} DaysRemainingFormat_t;

/**
 * @brief 定义卡片识读字段内容
 *
 */
typedef struct
{
  uint8_t CardType; // 卡类型
} TypeOfReadingFormat_t;

/**
 * @brief 实时时间字段内容
 *
 */
typedef struct
{
  uint32_t NowTimestamp;  // 当前时间
  uint8_t TimeZoneOffset; // 时区偏移
} RealTimeFormat_t;

/**
 * @brief 设备归属字段内容
 *
 */
typedef struct
{
  uint8_t ParkNumber;      // 园区号
  uint8_t BuildingNumber;  // 楼栋编码
  uint8_t FloorNumber;     // 楼层编码
  uint8_t ChildRommNumber; // 子房间编码
  uint32_t RoomNumber;     // 房间编码
} EquipmentOwnershipFormat_t;

/**
 * @brief 无线模组网络服装字段内容
 *
 */
typedef struct
{
  uint8_t OperationType;           // 操作类型
  uint8_t NetworkAttachmentStatus; // 网络附着状态
} WirelessModuleNetAttaFormat_t;

/**
 * @brief 设备握手字段内容
 *
 */
typedef struct
{
  uint8_t Count;                                 // 握手次数
  uint32_t UseEndTime;                           // 到期时间
  uint32_t CustomerCode;                         // 客户编码
  uint8_t CardStartSector;                       // 卡片起始访问扇区
  uint8_t MacAddr[PROTOCOL_INDEX_BIT_LENGTH];    // 设备编码
  uint8_t EncryptionKey[ENCRYPTION_KEY_LENGTH];  // 加密密钥
  uint8_t CardAccessKey[CRAD_SECTOR_KEY_LENGTH]; // 卡片访问密钥
  uint8_t AdminPassword[NUMBER_OF_KEYBOARD_KEY]; // 管理员密码
} DeviceHandshakeFormat_t;

/**
 * @brief 获取/清除特定卡类型顶替时间字段内容
 *
 */
typedef struct
{
  uint8_t Ident;        // 操作标识
  uint8_t CardType;     // 卡类型
  uint16_t ReplaceId;   // 顶替编码
  uint32_t ReplaceTime; // 顶替时间
} CardReplaceFormat_t;

/**
 * @brief 获取/设置免打扰字段内容
 *
 */
typedef struct
{
  uint8_t StartHour;   // 开始时
  uint8_t StartMinute; // 开始分
  uint8_t EndHour;     // 结束时
  uint8_t EndMinute;   // 结束分
} NoDisturbingFormat_t;

/**
 * @brief 门锁分类/分组字段内容
 *
 */
typedef struct
{
  uint32_t Group;        // 门锁分组
  uint16_t Lusters;      // 门锁分类
  uint8_t OperationType; // 操作类型
} LockClassificationFormat_t;

/**
 * @brief 定义本地注册状态字段内容
 *
 */
typedef struct 
{
  uint8_t Step;   // 本地注册步骤
  uint8_t Result; // 本地注册结果
} LocalRegisterStatusFormat_t;

/**
 * @brief 获取注册密钥数量
 *
 */
typedef struct
{
  uint16_t NumberOfRegisterKey;                          // 已注册密钥数量
  uint8_t NumberOfRegisterCardholder;                    // 已注册持卡人数量
  uint8_t UserName[USER_NAME_LENGTH];                    // 用户名
  uint8_t CardHolderList[PROTOCOL_ATTACHED_DATA_LENGTH]; // 已注册持卡人清单
} GetNumberOfRegisteredKeysFormat_t;

/**
 * @brief 查询持卡人信息字段内容
 *
 */
typedef struct
{
  uint8_t CardholderId;                                  // 持卡人编码
  uint8_t EndNumber;                                     // 结束序号
  uint8_t StartNumber;                                   // 起始序号
  uint16_t SizeOfProfile;                                // 描述文件数据长度
  uint8_t UserName[USER_NAME_LENGTH];                    // 用户名
  uint8_t Profile[MAX_CARDHOLDER_DESCRIBES_FILE_LENGTH]; // 持卡人描述文件
} QueryCardholderInformationFormat_t;

/**
 * @brief 新增持卡人字段内容
 *
 */
typedef struct
{
  uint8_t Date;                                     // 周期
  uint8_t Count;                                    // 次数
  uint8_t KeyType;                                  // 密钥类型
  uint32_t KeyToken;                                // 密钥编码
  uint32_t EndTimestamp;                            // 结束时间
  uint32_t StartTimestamp;                          // 开始时间
  uint8_t UserName[USER_NAME_LENGTH];               // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS];          // 时间段
  uint8_t KeyValue[USER_AUTHENTICATION_KEY_LENGTH]; // 密钥
} NewCardholderFormat_t;

/**
 * @brief 删除持卡人字段内容
 *
 */
typedef struct
{
  uint8_t KeyType;                                       // 密钥类型
  uint8_t UserName[USER_NAME_LENGTH];                    // 用户名
  uint8_t KeyValue[USER_AUTHENTICATION_KEY_LENGTH];      // 密钥
  uint8_t AdministratorPassword[NUMBER_OF_KEYBOARD_KEY]; // 管理员密码
} DeleteCardholderFormat_t;

/**
 * @brief 更新持卡人字段内容
 *
 */
typedef struct
{
  uint8_t Date;                                          // 周期
  uint8_t Count;                                         // 次数
  uint8_t KeyType;                                       // 密钥类型
  uint8_t UserStatus;                                    // 用户状态
  uint32_t EndTimestamp;                                 // 结束时间
  uint32_t StartTimestamp;                               // 开始时间
  uint8_t UserName[USER_NAME_LENGTH];                    // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS];               // 时间段
  uint8_t KeyValue[USER_AUTHENTICATION_KEY_LENGTH];      // 密钥
  uint8_t AdministratorPassword[NUMBER_OF_KEYBOARD_KEY]; // 管理员密码
} UpdateCardholderFormat_t;

/**
 * @brief 本地注册用户字段内容
 *
 */
typedef struct
{
  uint8_t Date;                                          // 周期
  uint8_t Count;                                         // 次数
  uint8_t KeyType;                                       // 密钥类型
  uint32_t KeyToken;                                     // 密钥编码
  uint32_t EndTimestamp;                                 // 结束时间
  uint32_t StartTimestamp;                               // 开始时间
  uint8_t UserName[USER_NAME_LENGTH];                    // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS];               // 时间段
  uint8_t AdministratorPassword[NUMBER_OF_KEYBOARD_KEY]; // 管理员密码
} LocalRegistrationFormat_t;

/**
 * @brief 上报持卡人信息字段内容
 *
 */
typedef struct
{
  uint8_t Date;                                     // 周期
  uint8_t Count;                                    // 次数
  uint8_t KeyType;                                  // 密钥类型
  uint32_t KeyToken;                                // 密钥编码
  uint32_t EndTimestamp;                            // 结束时间
  uint32_t StartTimestamp;                          // 开始时间
  uint8_t UserName[USER_NAME_LENGTH];               // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS];          // 时间段
  uint8_t KeyValue[USER_AUTHENTICATION_KEY_LENGTH]; // 密钥
} ReportCardholderInformationFormat_t;

/**
 * @brief 获取持卡人清单字段内容
 *
 */
typedef struct
{
  uint8_t NumberOfRegisterCardholder;                    // 已注册持卡人数量
  uint8_t CardHolderList[PROTOCOL_ATTACHED_DATA_LENGTH]; // 已注册持卡人清单
} GetCardholderListFormat_t;

/**
 * @brief 获取持卡人文件字段内容
 *
 */
typedef struct
{
  uint8_t CardholderList;                                // 持卡人序号
  uint16_t SizeOfProfile;                                // 描述文件数据长度
  uint8_t Profile[MAX_CARDHOLDER_DESCRIBES_FILE_LENGTH]; // 持卡人描述文件
} GetCardholderFilePacketFormat_t;

/**
 * @brief 远程开锁字段内容
 *
 */
typedef struct
{
  uint8_t UnlockingMode;                                 // 开锁方式
  uint8_t SignalQuality;                                 // 信号增益
  uint8_t BatteryCapacity;                               // 电池电量
  uint8_t UserId[USER_AUTHENTICATION_KEY_LENGTH];        // 授权ID
  uint8_t AdministratorPassword[NUMBER_OF_KEYBOARD_KEY]; // 超级管理员密码
} CommandUnlockFormat_t;

/**
 * @brief 二维码字段内容
 *
 */
typedef struct
{
  uint32_t EndTimeStamp;                                 // 结束时间
  uint32_t StartTimestamp;                               // 开始时间
  uint8_t UserId[USER_AUTHENTICATION_KEY_LENGTH];        // 授权ID
  uint8_t AdministratorPassword[NUMBER_OF_KEYBOARD_KEY]; // 超级管理员密码
} QrCodeDoorOpenFormat_t;

/**
 * @brief 蓝牙虚拟卡字段内容
 *
 */
typedef struct
{
  uint8_t Date;                                     // 周期
  uint8_t BatteryValue;                             // 电量百分比
  uint32_t EndTimestamp;                            // 结束时间
  uint32_t CreationTime;                            // 创建时间
  uint32_t StartTimestamp;                          // 开始时间
  uint32_t AuthorizationCode;                       // 授权编码
  uint8_t UserName[USER_NAME_LENGTH];               // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS];          // 时间段
  uint8_t KeyValue[USER_AUTHENTICATION_KEY_LENGTH]; // 密钥
} BluetoothVirtualCardFormat_t;

/**
 * @brief 网络属性数据包
 *
 */
typedef struct
{
  uint16_t PacketSize;                               // 消息有效长度
  uint8_t PacketData[PROTOCOL_ATTACHED_DATA_LENGTH]; // 消息内容
} NetworkAttributeDataPacket_t;

/**
 * @brief 固件属性
 *
 */
typedef struct
{
  uint32_t FileToken; // 用户授权ID
} FirmwareInformationFormat_t;

/**
 * @brief 通过文件注册用户字段内容
 *
 */
typedef struct
{
  uint8_t Date;                            // 周期
  uint8_t Count;                           // 次数
  uint32_t KeyToken;                       // 密钥编码
  uint8_t TotalFiles;                      // 文件总数量
  uint32_t EndTimestamp;                   // 结束时间
  uint32_t StartTimestamp;                 // 开始时间
  uint8_t UserName[USER_NAME_LENGTH];      // 用户名
  TimePeriod_t TimePeriod[MAX_TIME_SLOTS]; // 时间段
} RegisterUsersThroughFilesFormat_t;

/**
 * @brief 下发文件属性
 *
 */
typedef struct
{
  uint8_t FileType;                                // 文件类型
  uint32_t FileSize;                               // 文件大小
  FirmwareInformationFormat_t Firmware;            // 固件属性
  RegisterUsersThroughFilesFormat_t RegisterUsers; // 注册用户属性
} PropertieOfIssuedDocumentsFormat_t;

/**
 * @brief 文件下发字段内容
 *
 */
typedef struct
{
  uint8_t FileType;                                    // 文件类型
  uint32_t FileToken;                                  // 文件令牌
  uint32_t WriteOffset;                                // 文件偏移
  uint16_t WritePacketSize;                            // 数据长度
  uint8_t WriteDatePacket[SINGLE_REQUEST_FILE_LENGTH]; // 文件数据
} FileDeliveryFormat_t;

/**
 * @brief 日志上报字段内容
 *
 */
typedef struct
{
  uint8_t Type;                                 // 类型
  uint8_t Parameter;                            // 参数
  uint32_t TriggerTime;                         // 触发时间
  uint8_t DataPacket[LOG_ATTACHED_DATA_LENGTH]; // 日志附带数据
} RealUploadEventFormat_t;

/**
 * @brief 获取缓存日志总数量
 *
 */
typedef struct
{
  uint16_t NumberOfLogFile; // 日志文件数量
} ObtainTheNumberOfogFilesFormat_t;

/**
 * @brief 获取日志文件字段内容
 *
 */
typedef struct
{
  uint8_t NumberOfGet;                                         // 获取日志条数
  uint16_t StartLogTableId;                                    // 起始序号
  uint16_t SizeOfLogDataPacket;                                // 文件长度
  uint8_t LogDataPacket[OBTAIN_THE_LOG_FILE_LENGTH_EACH_TIME]; // 日志文件
} GetLogFileFormat_t;

/**
 * @brief 外部验证字段内容
 *
 */
typedef struct
{
  uint8_t KeyType;                          // 密钥类型
  uint8_t KeyValue[TYPE_THE_LENGTH_OF_KEY]; // 待验证的密钥
} ExterlalValidationeFormat_t;

/**
 * @brief 测试命令字段内容
 *
 */
typedef struct
{
  uint16_t DataLength;                                       // 数据长度
  uint8_t DataPacket[SINGLE_COMMUNICATION_TEST_DATA_LENGTH]; // 附带数据
} ConnectTestFormat_t;

/**
 * @brief 定义协议栈字段内容
 *
 */
typedef struct
{
  uint8_t SyncwordCode;                             // 帧头
  uint8_t Length[PROTOCOL_DATA_SIZE_BIT_LENGTH];    // 附带数据长度
  uint8_t Random[PROTOCOL_RANDOM_BIT_LENGTH];       // 随机数
  uint8_t TimeStamp[PROTOCOL_TIMESTAMP_BIT_LENGTH]; // 时间戳
  uint8_t Index[PROTOCOL_INDEX_BIT_LENGTH];         // 设备索引
  uint8_t Captcha[PROTOCOL_CAPTCHA_BIT_LENGTH];     // 验证码
  uint8_t Version;                                  // 协议版本
  uint8_t Command;                                  // 主命令
  uint8_t Data[PROTOCOL_ATTACHED_DATA_LENGTH];      // 附带数据
} ProtocolFormat_t;

typedef void (*MessageResponse_t)(const uint8_t *, uint16_t, uint8_t *, uint16_t *);

/**
 * @brief 验证报文有效性
 *
 * @param pDataIn  - 输入报文
 * @param SizeIn   - 报文长度
 * @return uint8_t - 验证状态
 */
extern uint8_t ProtocolSumCrcCheck(const uint8_t *pDataIn, uint16_t DataSize);

/**
 * @brief 解析输入报文
 *
 * @param pDataIn           - 输入报文
 * @param DataSize          - 输入报文数据长度
 * @param pDataOut          - 输出解析后应答的报文
 * @param pSizeOut          - 输出报文数据长度
 * @param pCommandOut       - 报文命令
 * @param pBasisOfSearchOut - 报文检索编码
 */
extern void ProtocolParsingInputMessages(uint8_t *pDataIn, uint16_t DataSize, uint8_t *pDataOut, uint16_t *pSizeOut, uint8_t *pCommandOut, uint32_t *pBasisOfSearchOut);

/**
 * @brief 构建心跳报文
 *
 * @param DeviceType        - 设备类型
 * @param PercentageOfPower - 剩余电量百分比
 * @param Rssi              - 通讯质量
 * @param MessageHandle     - 消息句柄
 * @param pMessageOut       - 输出构建后的报文
 * @param pMessageSizeOut   - 构建后的报文的长度
 * @return bool             - 构建状态（true：成功 false：失败）
 */
extern bool ProtocolBuildHeartbeatMessage(uint8_t DeviceType, uint8_t PercentageOfPower, uint8_t Rssi, uint32_t MessageHandle, uint8_t *pMessageOut, uint16_t *pMessageSizeOut);

/**
 * @brief 构建远程开锁报文
 *
 * @param MessageHandle     - 消息句柄
 * @param pMessageOut       - 输出构建后的报文
 * @param pMessageSizeOut   - 构建后的报文的长度
 * @return bool             - 构建状态（true：成功 false：失败）
 */
extern bool ProtocolBuildLockOpenMessage(uint32_t MessageHandle, uint8_t *pMessageOut, uint16_t *pMessageSizeOut);
/**
 * @brief 构建本地注册结果
 *
 * @param pInformationIn  - 持卡人信息
 * @param Result          - 注册结果
 * @param MessageHandle   - 消息句柄
 * @param pMessageOut     - 输出构建后的报文
 * @param pMessageSizeOut - 构建后的报文的长度
 * @return bool           - 构建状态（true：成功 false：失败）
 */
extern bool ProtocolBuildLocalRegisterResultMessage(ReportCardholderInformationFormat_t *pInformationIn, uint8_t Result, uint32_t MessageHandle, uint8_t *pMessageOut, uint16_t *pMessageSizeOut);

/**
 * @brief 构建事件上报报文
 *
 * @param pEventInformationIn - 事件属性
 * @param MessageHandle       - 消息句柄
 * @param pMessageOut         - 输出构建后的报文
 * @param pMessageSizeOut     - 构建后的报文的长度
 * @return bool               - 构建状态（true：成功 false：失败）
 */
extern bool ProtocolBuildIncidentReportingMessage(RealUploadEventFormat_t *pEventInformationIn, uint32_t MessageHandle, uint8_t *pMessageOut, uint16_t *pMessageSizeOut);

/**
 * @brief 构建外部主机验证报文
 *
 * @param pExterlalValidationeIn - 待验证的密钥信息
 * @param MessageHandle       - 消息句柄
 * @param pMessageOut         - 输出构建后的报文
 * @param pMessageSizeOut     - 构建后的报文的长度
 * @return bool               - 构建状态（true：成功 false：失败）
 */
extern bool ProtocolBuildExternalHostValidationMessage(ExterlalValidationeFormat_t *pExterlalValidationeIn, uint32_t MessageHandle, uint8_t *pMessageOut, uint16_t *pMessageSizeOut);

#endif
